

<template>
  <div
    style="height: 100%; width: 100%; overflow: hidden"
    :class="{ 'light-bg': pattern == '2' }"
  >
    <!-- <div class="interval-tab">
       <span
         @click="
           changeSymbol({
             pair_ca: '0x49D37E82390348780444f40929bF233F72e40Ae6',
             chain_id:'8453'
           })
         "
         >ETH</span
       >
       <span
         @click="
           changeSymbol({
             pair_ca: '0x7fe382B1C10Fc4bcB5b018701eb6CcC09eDBF83c',
             chain_id:'8453'
           })
         "
         >USDT</span
       >
       <span
         @click="
           changeSymbol({
             pair_ca: '0xa1bf0e900fb272089c9fd299ea14bfccb1d1c2c0',
             chain_id:'1'
           })
         "
         >SOL</span
       >
       <span @click="refreshTv"> 刷新1 </span>
     </div> -->
    <div>
      <div class="interval-tab">
        <span
          @click="changeInterval('1s')"
          :class="{ active: interval == '1s' }"
          >分时</span
        >
        <span @click="changeInterval('1')" :class="{ active: interval == '1' }"
          >1分</span
        >
        <span @click="changeInterval('5')" :class="{ active: interval == '5' }"
          >5分</span
        >
        <span
          @click="changeInterval('15')"
          :class="{ active: interval == '15' }"
          >15分</span
        >
        <span
          @click="changeInterval('60')"
          :class="{ active: interval == '60' }"
          >1小时</span
        >
        <span
          @click="changeInterval('240')"
          :class="{ active: interval == '240' }"
          >4小时</span
        >
        <span
          @click="changeInterval('720')"
          :class="{ active: interval == '720' }"
          >12小时</span
        >
        <span
          @click="changeInterval('1D')"
          :class="{ active: interval == '1D' }"
          >24小时</span
        >
      </div>
    </div>
    <div class="k-line-area">
      <div id="tv_chart_container" style="height: 100%; width: 100%"></div>
      <div class="loading-indicator" v-show="isLoadingTv">
        <div class="tv-spinner"></div>
      </div>
    </div>
    <div class="study-area">
      <div class="study-area-left">
        <span
          @click="setMainIndicator('MA')"
          :class="{ active: isCreateStudyMain['MA'] }"
          >MA</span
        >
        <span
          @click="setMainIndicator('EMA')"
          :class="{ active: isCreateStudyMain['EMA'] }"
        >
          EMA
        </span>
        <span
          @click="setMainIndicator('BOLL')"
          :class="{ active: isCreateStudyMain['BOLL'] }"
          >BOLL</span
        >
        <span
          @click="setMainIndicator('SAR')"
          :class="{ active: isCreateStudyMain['SAR'] }"
          >SAR</span
        >
      </div>
      |
      <div class="study-area-right">
        <span
          @click="setSubIndicator('VOL')"
          :class="{ active: isCreateStudySub['VOL'] }"
          >VOL</span
        >
        <span
          @click="setSubIndicator('MACD')"
          :class="{ active: isCreateStudySub['MACD'] }"
          >MACD</span
        >
        <span
          @click="setSubIndicator('KDJ')"
          :class="{ active: isCreateStudySub['KDJ'] }"
          >KDJ</span
        >
        <span
          @click="setSubIndicator('BOLL')"
          :class="{ active: isCreateStudySub['BOLL'] }"
          >BOLL</span
        >
        <span
          @click="setSubIndicator('RSI')"
          :class="{ active: isCreateStudySub['RSI'] }"
          >RSI</span
        >
        <span
          @click="setSubIndicator('OBV')"
          :class="{ active: isCreateStudySub['OBV'] }"
          >OBV</span
        >
        <span
          @click="setSubIndicator('TRIX')"
          :class="{ active: isCreateStudySub['TRIX'] }"
          >TRIX</span
        >
      </div>
    </div>
  </div>
</template>
 <script setup>
import { nextTick, onMounted, onUnmounted, reactive, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { init, dispose, registerOverlay } from "../utils/echarts";
import * as api from "../api/api_path";
import { tE } from "../utils/flt";
import config from "../klineStyles";
import { useSocket } from "../utils/socket";
import { data } from "../api/response.json";
import uTimes from "../utils/times";
let chart = null;
const route = useRoute();
const pattern = route.query.pattern || 1;
const isShow = ref(false);
const { socket, send, on, off } = useSocket("wss://stream.dexx.ai/stream", {});
  
const timeDefault =localStorage.getItem('timeDefault')
const interval = ref(timeDefault || "15");
const isLoadingTv = ref(false);
const pair_ca = route.query.pair_ca;
const chain_id = route.query.chain_id;
const symbolInfo = ref({
  pair_ca: pair_ca || "0xA43fe16908251ee70EF74718545e4FE6C5cCEc9f",
  chain_id: chain_id || 1,
});
const isCreateStudyMain = reactive({
  MA: false,
  EMA: false,
  BOLL: false,
  SAR: false,
});
const isCreateStudySub = reactive({
  BOLL: false,
  VOL: false,
  MACD: false,
  KDJ: false,
  TRIX: false,
  RSI: false,
  OBV: false,
});
window.updateWidget = updateWidget;
window.refreshTv = refreshTv;
window.changeSymbol = changeSymbol;

onMounted(async () => {
  // ios 触摸问题
  document.getElementById("tv_chart_container").addEventListener(
    "touchstart",
    function (event) {
      // 阻止默认行为
      event.preventDefault();
    },
    {
      passive: false,
    }
  );
  document
    .getElementById("tv_chart_container")
    .addEventListener("mousedown", function (event) {
      event.preventDefault();
    });
  //初始化
  console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
  chart = init("tv_chart_container", {
    styles: {
      grid: config.grid(pattern),
      candle: config.candle(),
      yAxis: config.yAxis(pattern),
      xAxis: config.yAxis(pattern),
      separator: config.separator(pattern),
      indicator: config.indicator(),
      crosshair: config.crosshair(pattern),
    },
    timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,
    locale: "zh-CN",
    customApi: {
      formatBigNumber: (value) => {
        return tE(value);
      },
    },
  });
  //精度
  chart.setPriceVolumePrecision({
    pricePrecision: 17,
  });
  setMainIndicator("MA");
  setSubIndicator('VOL');
  //加载更多
  chart.loadMore(async (timestamp) => {
    let klineHisList = await getKlineHistoryList({
      ...symbolInfo.value,
      to_timestamp: timestamp / 1000,
    });
    chart.applyMoreData(
      klineHisList,
      klineHisList.length >= symbolInfo.value.limit
    );
  });

  socket.on("open", (event) => {});
  socket.on("message", (res) => {
    res = JSON.parse(res);
    if (res && res.action === "connect") {
      socketKlineData();
      // setUpdateData()
    }
    if (res && res.data) {
      let data = res.data;
      // console.log(data);
      if (res.channel == "token_kline" && data && data[0].pair_addr == symbolInfo.value.pair_ca) {
        const dataList = chart.getDataList();
        const lastData = dataList[dataList.length - 1];
        const newData = { ...lastData };
       
        if (1e3 * data[0].timestamp != lastData.timestamp) {
          newData.open = lastData.close;
          newData.timestamp = Number(1e3 * data[0].timestamp);
          newData.close = lastData.close;
          newData.low = lastData.close;
          newData.high = lastData.close;
          newData.volume = data[0].volume;
        } else {
          newData.volume = data[0].volume;
          newData.close = data[0].close_price;
          newData.low = data[0].low_price;
          newData.high = data[0].high_price;
          // if (newData.high < data[0].close_price) {
          //   newData.high = data[0].close_price;
          // }
          // if (newData.low > data[0].close_price) {
          //   newData.low = data[0].close_price;
          // }
        }
        console.log(newData,data);
        //更新数据
        chart.updateData(newData);
      }
    }
  });
});

if (import.meta.env.MODE === "development") {
  updateWidget(symbolInfo.value);
}
// 切换时间
async function changeInterval(time) {
  interval.value = time;
  localStorage.setItem('timeDefault',time)
  await updateWidget({ ...symbolInfo.value, kline_interval: time });
  if (interval.value == "1s") {
    chart.setStyles({ candle: { type: "area" } });
  } else {
    chart.setStyles({ candle: { type: "candle_solid" } });
  }
  closeSendKline();
  socketKlineData();
}
//切换pai
function changeSymbol(info) {
  let params = {
    ...symbolInfo.value,
    pair_ca: info.pair_ca,
    chain_id: info.chain_id,
  }
  symbolInfo.value=params;
  updateWidget(params);
  closeSendKline();
  socketKlineData();
}
// 更新
async function updateWidget(params) {
  let prames = {
    pair_ca: params.pair_ca,
    chain_id: params.chain_id,
    from_timestamp: 1717291443,
    to_timestamp: Math.floor(Date.now() / 1000),
    limit: 200,
    kline_interval: uTimes(interval.value),
  };
  symbolInfo.value = prames;
  isLoadingTv.value = true;
  let klineHisList = await getKlineHistoryList(prames);
  isLoadingTv.value = false;
  chart.applyNewData(klineHisList, klineHisList.length >= prames.limit);
  isShow.value = true;
  // if(socket.ws.readyState===1){
  //   closeSendKline();
  //   socketKlineData();
  // }
  // chart.createOverlay('simpleTag')
  // chart.createOverlay({
  //   name: "simpleAnnotation",
  //   extendData: "B",
  //   styles:config.overlay('B'),
  //   points: [
  //     { timestamp: klineHisList[klineHisList.length-5].timestamp, value: klineHisList[klineHisList.length-5].low },
  //   ],
  // });
  // chart.createOverlay({
  //   name: "simpleAnnotation",
  //   extendData: "S",
  //   styles:config.overlay('S'),
  //   points: [
  //     { timestamp: klineHisList[klineHisList.length-15].timestamp, value: klineHisList[klineHisList.length-15].high  },
  //   ],
  // });
}
async function closeSendKline() {
  await socket.send(
    JSON.stringify({
      id: symbolInfo.value.id || "1",
      action: "unsubscribe",
      channel: "token_kline",
      data: {
        chain: symbolInfo.value.chain_id.toString(),
      },
    })
  );
}
async function socketKlineData() {
  await socket.send(
    JSON.stringify({
      id: "1",
      action: "subscribe",
      channel: "token_kline",
      data: {
        chain: symbolInfo.value.chain_id.toString(),
        address: symbolInfo.value.pair_ca,
        interval: uTimes(interval.value),
      },
    })
  );
}
//  let barsTimes=[]
// 获取历史数据
async function getKlineHistoryList(params) {
  let res = await api.tvs.quoteHis(params);
  let datas = res.data;
  // let datas = data;
  let bars = [];
  for (let i = 0; i < datas.length; i++) {
    bars.push({
      timestamp: Number(1e3 * datas[i].timestamp),
      open: Number(datas[i].open),
      close: Number(datas[i].close),
      high: Number(datas[i].high),
      low: Number(datas[i].low),
      volume: Number(datas[i].volume),
      turnover:Number(datas[i].turnover)
    });
  }
  // if(params.kline_interval!=='1s'){
  //    barsTimes=bars;
  // }

  return bars;
  // return params.kline_interval!=='1s'?bars:barsTimes;
}
//主图指标
let lastMainName = null;
function setMainIndicator(name) {
  // let paneAll = chart.getIndicatorByPaneId("candle_pane");
  // if (paneAll.size > 1) {
  //   chart.removeIndicator("candle_pane", lastMainName);
  //   isCreateStudyMain[lastMainName] = !isCreateStudyMain[lastMainName];
  // }
  if (isCreateStudyMain[name]) {
    chart.removeIndicator("candle_pane", name);
  } else {
    chart.createIndicator(name, true, { id: "candle_pane" });
  }
  lastMainName = name;
  isCreateStudyMain[name] = !isCreateStudyMain[name];
}
let lastName = null;
//副图指标添加
function setSubIndicator(name) {
  let paneAll = chart.getIndicatorByPaneId();
  if (paneAll.size > 3) {
    chart.removeIndicator(lastName);
    isCreateStudySub[lastName] = !isCreateStudySub[lastName];
  }
  if (isCreateStudySub[name]) {
    chart.removeIndicator(name);
  } else {
    chart.createIndicator(name, false, { id: name });
    chart.setPaneOptions({
      id: name,
      height: 50,
    });
  }
  lastName = name;
  isCreateStudySub[name] = !isCreateStudySub[name];
}
function refreshTv() {
  chart.scrollToRealTime();
}
onUnmounted(() => {
  dispose("tv_chart_container");
});
</script>
 <style lang="less" scoped>
.k-line-area {
  height: calc(100% - 82px);
  position: relative;
}
.study-area,
.interval-tab {
  color: #6d7280;
  height: 40px;
  display: flex;
  align-items: center;
  font-size: 12px;
  overflow: auto;
  white-space: nowrap;
  justify-content: center;
  &::-webkit-scrollbar {
    width: 0px; /* 对于垂直滚动条，设置宽度 */
    height: 0px; /* 对于水平滚动条，设置高度 */
  }
  span {
    display: inline-block;
    padding: 2px 8px 2px 8px;
    line-height: 24px;
    margin-left: 2px;
    text-align: center;
    // min-width: 53px;
    white-space: nowrap;
    border-radius: 6px;
    &:hover {
      cursor: pointer;
    }
    &.active {
      font-weight: bold;
    }
  }
}
#tv_chart_container::before {
  content: "";
  position: absolute;
  height: 20px;
  width: 80px;
  top: calc(50% - 20px);
  left: calc(50% - 40px);
  z-index: 9999;
  background-image: url(../../public/logo.png);
  background-size: 100% 100%;
}
.study-area {
  border-top: 1px solid #eee;
  position: fixed;
  left: 0;
  right: 0;
  // top: -20px;
  bottom: 0;
  z-index: 9999;
  background: #fff;

  .study-area-left {
    // width: 164px;
    padding: 0 16px;
    span {
      padding: 2px 0;
      margin-right: 10px;
      color: #a0a6b2;
      &:last-child {
        margin-right: 0;
      }
      // margin-left: 8px;
    }
  }
  .study-area-right {
    width: calc(100% - 186px);
    overflow: auto;
    display: flex;
    margin-left: 8px;
    color: #a0a6b2;
    &::-webkit-scrollbar {
      scrollbar-width: none;
      scrollbar-color: none;
      width: 0; /* 对于垂直滚动条，设置宽度 */
      height: 0; /* 对于水平滚动条，设置高度 */
    }
    span {
      padding: 2px 0;
      margin-right: 8px;
      color: #a0a6b2;
      &:last-child {
        padding-right: 16px;
      }
    }
  }
  span {
    &.active {
      font-weight: normal;
      color: #1b1e26;
    }
  }
}
.interval-tab {
  background: #fff;
  border-bottom: 1px solid #eee;
  span {
    &.active {
      background-color: #f0f3fa;
    }
  }
}

.light-bg {
  background-color: #212530;
  color: #ddd;
  .loading-indicator {
    background-color: rgba(33, 37, 48, 0.4);
  }
  .study-area {
    border-top: 1px solid #35373a;
    background: #212530;
    span {
      &.active {
        color: #fff;
      }
    }
  }
  .interval-tab {
    border-bottom: 1px solid #35373a;
    background: #212530;
    span {
      &.active {
        color: #fff;
        font-weight: bold;
        background: #292d3a;
      }
    }
  }
}

.loading-indicator {
  background: rgba(255, 255, 255, 0.4);
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  z-index: 1999;

  .tv-spinner {
    animation: tv-spinner__container-rotate-aLqboHuu 0.9s linear infinite;
    border-bottom: 4px solid #8797a533;
    border-left: 4px solid #8797a533;
    border-radius: 50%;
    border-right: 4px solid #8797a533;
    border-top: 4px solid #8797a533;

    border-left-color: rgba(255, 211, 32, 0.4); // rgba(225, 81, 81, 0.4);
    border-top-color: rgba(255, 211, 32, 0.4);
    height: 50px;
    left: calc(50% - 25px);
    margin: 0 auto;
    position: absolute;
    top: calc(50% - 25px);
    width: 50px;
  }
}

@keyframes tv-spinner__container-rotate-aLqboHuu {
  to {
    transform: rotate(1turn);
  }
}
</style>